package com.ziven.common.widget.value;

import android.view.View;

import androidx.annotation.NonNull;

import com.ziven.easygo.util.Carry;
import com.ziven.easygo.util.ViewHelper;

/**
 * @author Ziven
 */
public final class Values {

    private Values() {}

    public static Value value(Object object) {
        return new Value() {
            @Override
            protected void takeEffect(@NonNull ViewHelper<? extends View> helper) {
                //Do nothing
            }
        }.value(object);
    }

    public static Value mergeNew(@NonNull Value value1,
                                 @NonNull Value value2) {
        return TakeEffect.values(value1, value2);
    }

    public static Value mergeRemove(@NonNull Value value1,
                                    @NonNull Value value2) {
        remove(value1, value2);
        return mergeNew(value1, value2);
    }

    public static void remove(@NonNull Value value,
                              @NonNull Value remove) {
        forEachAll(remove,
                v1 -> forEachAll(value,
                        v2 -> v2.myself(MixValue.class,
                                v3 -> v3.remove(v1))));
    }

    public static boolean replace(@NonNull Value value,
                                  @NonNull Value replace) {
        Value find = find(value, replace);
        replace.copy(find);
        return !find.isNullValue();
    }

    public static boolean copy(@NonNull Value value,
                               @NonNull Value copy) {
        return !find(value, copy).copy(copy).isNullValue();
    }

    @NonNull
    public static Value find(@NonNull Value value,
                             @NonNull Value find) {
        if(value.equals(find)) {
            return value;
        }
        if(value instanceof MixValue) {
            Value v2;
            for(Value v1 : ((MixValue) value).obtain()) {
                if(!(v2 = find(v1, find)).isNullValue()) {
                    return v2;
                }
            }
        }
        return NullValue.VALUE;
    }

    public static void forEachAll(@NonNull Value value,
                                  @NonNull Carry<Value> carry) {
        carry.carry(value);
        forEachMix(value, v -> forEachAll(v, carry));
    }

    public static void forEachMixAndMy(@NonNull Value value,
                                       @NonNull Carry<Value> carry) {
        carry.carry(value);
        forEachMix(value, carry);
    }

    public static void forEachMix(@NonNull Value value,
                                  @NonNull Carry<Value> carry) {
        value.myself(MixValue.class, my -> my.forEach(carry));
    }
}
